<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Canvas Bar Chart</title>
  <style>
  body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
  }
  canvas {
    border: 1px solid #ccc;
  }
  </style>
</head>
<body>
<canvas id="barChart" width="600" height="400"></canvas>
<script>
  // 数据集
  const data = [30, 90, 60, 120, 75];
  const labels = ['A', 'B', 'C', 'D', 'E'];
  // 获取 canvas 和绘图上下文
  const canvas = document.getElementById('barChart');
  const ctx = canvas.getContext('2d');
  const scaleStep = 20;
  {
    // 设置图表参数，增加四周的边距
    const margin = { top: 50, right: 50, bottom: 50, left: 50 }; // 四周的边距
    const chartWidth = canvas.width - margin.left - margin.right;
    const chartHeight = canvas.height - margin.top - margin.bottom;
    const barWidth = (chartWidth / data.length) * 0.8; // 柱子宽度，留出一些间距
    const barSpacing = (chartWidth - barWidth * data.length) / (data.length + 1);
    const maxValue = Math.max(...data);
    const yScale = chartHeight / maxValue;
    // 绘制 Y 轴刻度线和标签，调整起始位置以考虑顶部边距
    for (let i = 0; i <= maxValue; i += scaleStep) {
      const y = chartHeight - (i * yScale) + margin.top;
      ctx.beginPath();
      ctx.moveTo(margin.left, y);
      ctx.lineTo(margin.left - 5, y); // 减少5个像素以使刻度线更短
      ctx.stroke();
      // ctx.save();
      ctx.fillText(i, margin.left - 15, y + 2); // 标签向左移20像素
      ctx.textAlign = 'right';
      ctx.textBaseline = 'middle';
      ctx.font = '14px Times New Roman';
      // ctx.restore();
    }
    // 绘制柱子，考虑左边距和底部边距
    data.forEach((value, index) => {
      const x = margin.left + (index + 1) * barSpacing + index * barWidth;
      const y = chartHeight - (value * yScale) + margin.top;
      const height = value * yScale;
      ctx.fillStyle = 'steelblue';
      ctx.fillRect(x, y, barWidth, height);
      // X轴标签也需考虑底部边距
      ctx.textAlign = 'center';
      ctx.textBaseline = 'top';
      ctx.fillText(labels[index], x + barWidth / 2, canvas.height - margin.bottom + 10);
    });
    // 绘制 X 和 Y 轴线，考虑所有边距
    ctx.beginPath();
    ctx.moveTo(margin.left, margin.top);
    ctx.lineTo(margin.left, chartHeight + margin.top);
    ctx.lineTo(chartWidth + margin.left, chartHeight + margin.top);
    ctx.stroke();
  }
</script>
</body>
</html>
